// import Decimal from 'decimal.js';
import Big from "big.js";
import { udp } from "@cscec/udp-mobile-ui";
// import { IAppInfo } from "@cscec/cip-component/es/UdpGridView";

/**
 * 减法计算
 * @param arg1
 * @param arg2
 * @returns 返回类型为string
 */
export function sub(arg1: number | string = 0, arg2: number | string = 0) {
  try {
    return Big(`${arg1}`.trim() === "" ? 0 : arg1)
      .minus(Big(`${arg2 ?? 0}`.trim() === "" ? 0 : arg2 ?? 0))
      .toString();
  } catch (error) {
    console.error(`减法计算异常, arg1:${arg1}, arg2:${arg2}`, error);
    return "";
  }
}
/**
 *
 * @param arg1 被除数
 * @param arg2 除数
 * @returns 返回类型为string
 */
export function div(arg1: number | string = 0, arg2: number | string = 1, arg3?: number) {
  try {
    // 被除数为0时 返回空
    arg3 = arg3 !== undefined ? arg3 : 2;
    if (+arg2 === 0) return "";
    return Big(`${arg1}`.trim() === "" ? 0 : arg1)
      .div(Big(`${arg2}`.trim() === "" ? 1 : arg2))
      .toFixed(arg3)
      .toString();
  } catch (error) {
    console.error(`除法计算异常, arg1:${arg1}, arg2:${arg2}`, error);
    return "";
  }
}

/**
* 乘法计算
* @param arg1
* @param arg2
* @returns 返回类型为string
*/
export function mul(arg1: number | string = 1, arg2: number | string = 1) {
  try {
    return Big(`${arg1}`.trim() === "" ? 1 : arg1)
      .times(Big(`${arg2}`.trim() === "" ? 1 : arg2))
      .toString();
  } catch (error) {
    console.error(`乘法计算异常, arg1:${arg1}, arg2:${arg2}`, error);
    return "";
  }
}


/**
 * 获取精度
 * @param type
 */
export function getPrecision(type?: PrecisionType) {
  const dvaState = udp.getPageInstance().getDvaState() || {};
  // 配置精度
  const appInfo = dvaState.appInfo || {
    amtPrecision: 2,
    pricePrecision: 2,
    qtyPrecision: 3,
    ratePrecision: 4,
  };
  switch (type) {
    case "amt":
      return appInfo.amtPrecision;
    case "prc":
      return appInfo.pricePrecision;
    case "qty":
      return appInfo.qtyPrecision;
    case "rate":
      return appInfo.ratePrecision;
    default:
      return 2;
  }
}


/**
 * 格式化方法 - 返回string
 * @param val 需要格式化的值
 * @param type 精度类型
 * @param mode 舍入模式 默认四舍五入
 */
export function format(
  val: CalcValueType | any,
  type?: PrecisionType,
  mode?: RoundMode
) {
  switch (typeof val) {
    case "number":
      return Big(val).toFixed(
        getPrecision(type),
        mode ?? ROUND_MODE.ROUND_HALF_UP
      );
    case "string":
      return Big(`${val}`.trim() === "" ? 0 : val).toFixed(
        getPrecision(type),
        mode ?? ROUND_MODE.ROUND_HALF_UP
      );
    case "object":
      if (val instanceof Big) {
        return val.toFixed(
          getPrecision(type),
          mode ?? ROUND_MODE.ROUND_HALF_UP
        );
      } else {
        // 遍历对象的属性，属性名称包含amt prc qty rate则进行精度处理
        let obj = val;
        for (const key in obj) {
          const element = obj[key];
          if (obj.hasOwnProperty(key) && element !== undefined) {
            if (key.toLowerCase().includes("amt")) {
              obj[key] = format(element, PRECISION_TYPE.AMT, mode);
            } else if (key.toLowerCase().includes("prc")) {
              obj[key] = format(element, PRECISION_TYPE.PRC, mode);
            } else if (key.toLowerCase().includes("qty")) {
              obj[key] = format(element, PRECISION_TYPE.QTY, mode);
            } else if (key.toLowerCase().includes("rate")) {
              obj[key] = format(element, PRECISION_TYPE.RATE, mode);
            } else {
              obj[key] = element;
            }
          }
        }
        return obj;
      }
    default:
      return val;
  }
}

/**
 * 精度类型
 */
export const PRECISION_TYPE = {
  // 合价精度
  AMT: "amt",
  // 单价精度
  PRC: "prc",
  // 工程量精度
  QTY: "qty",
  // 百分比精度
  RATE: "rate",
} as const;

/**
 * 舍入模式
 */
export const ROUND_MODE = {
  // 向下取整
  ROUND_DOWN: 0,
  // 四舍五入
  ROUND_HALF_UP: 1,
  // 银行家舍入 - 四舍六入五成双
  ROUND_HALF_EVEND: 2,
  // 向上取整
  ROUND_UP: 3,
} as const;

export type PrecisionType =
  (typeof PRECISION_TYPE)[keyof typeof PRECISION_TYPE];
type RoundMode = (typeof ROUND_MODE)[keyof typeof ROUND_MODE];
export type CalcValueType = number | string | Big | object;

/**
* 格式化方法 - 返回number
* @param val 需要格式化的值
* @param type 精度类型
* @param mode 舍入模式 默认四舍五入
*/
export function formatNum(
  val: CalcValueType | any,
  type?: PrecisionType,
  mode?: RoundMode
) {
  switch (typeof val) {
    case "number":
    case "string":
      return Number(format(val, type, mode));
    case "object":
      if (val instanceof Big) {
        return Number(format(val, type, mode));
      } else {
        // 遍历对象的属性，属性名称包含amt prc qty rate则进行精度处理
        let obj = val;
        for (const key in obj) {
          const element = obj[key];
          if (obj.hasOwnProperty(key) && element !== undefined) {
            if (key.toLowerCase().includes("amt")) {
              obj[key] = Number(format(element, PRECISION_TYPE.AMT, mode));
            } else if (key.toLowerCase().includes("prc")) {
              obj[key] = Number(format(element, PRECISION_TYPE.PRC, mode));
            } else if (key.toLowerCase().includes("qty")) {
              obj[key] = Number(format(element, PRECISION_TYPE.QTY, mode));
            } else if (key.toLowerCase().includes("rate")) {
              obj[key] = Number(format(element, PRECISION_TYPE.RATE, mode));
            } else {
              obj[key] = element;
            }
          }
        }
        return obj;
      }
    default:
      return val;
  }
}

